/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * UserComplexImport.java
 *
 * Created on Jan 10, 2011, 3:25:54 PM
 */

package relationship.complex.importing;

import relationship.complex.creation.ComplexRelationshipInfo;
import relationship.complex.creation.VerifyRegexWithClasses;
import relationship.complex.dataTypes.RelationshipDef;
import relationship.complex.dataTypes.ComplexRelImportReturn;
import relationship.importing.iFinished;
import resultEditor.annotations.Annotation;
import resultEditor.annotations.AnnotationRelationship;
import resultEditor.annotations.Depot;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Vector;

/**
 *
 * @author Kyle
 */
public class UserComplexImport extends javax.swing.JFrame {
    //<editor-fold defaultstate="collapsed" desc="Member Variables">
    private ArrayList<ComplexRelImportReturn> unknownRels = new ArrayList<ComplexRelImportReturn>();
    private int position;
    private iFinished caller;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * The constructor for a Complex Relationship importing gui.
     * @param guiX - the X position of the calling GUI.
     * @param guiY - the Y position of the calling GUI.
     * @param width - the Width of the calling GUI.
     * @param height - the Height of the calling GUI.
     * @param toUse - the Collection of Complex Relationships that are being imported.
     */
    public UserComplexImport(int guiX, int guiY, int width, int height,Collection<ComplexRelImportReturn> toUse, iFinished caller)
    {
        this.caller = caller;
        position = 0;
        unknownRels.addAll(toUse);
        //Init gui components ***DO NOT ATTEMPT TO USE COMPONENTS BEFORE THIS LINE!!!*****
        initComponents();
        //Popuolate gui components with initial information
        updateInfo();
        setButtonsBasedOnValidity();
        if(unknownRels.size() ==1)
            next.setText("Done");

        //set dialog location to center of parent GUI.
        int x = 0;
        int y = 0;

        int eHOSTx = guiX; int eHOSTy = guiY;
        x = eHOSTx + (int)((width-this.getWidth())/2);
        y = eHOSTy + (int)((height-this.getHeight())/2);

        this.setLocation(x, y);
    }
    //</editor-fold>

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        Head = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        End = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jPanel9 = new javax.swing.JPanel();
        BodyTitle = new javax.swing.JLabel();
        nameLabel = new javax.swing.JTextField();
        jPanel6 = new javax.swing.JPanel();
        userRegex = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jButton2 = new javax.swing.JButton();
        jPanel4 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        jPanel8 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jPanel7 = new javax.swing.JPanel();
        skipAll = new javax.swing.JButton();
        skip = new javax.swing.JButton();
        next = new javax.swing.JButton();
        Body = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        importedInfoList = new javax.swing.JList();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Relationship Importer");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        Head.setLayout(new java.awt.BorderLayout());

        jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        jTextArea1.setColumns(20);
        jTextArea1.setEditable(false);
        jTextArea1.setLineWrap(true);
        jTextArea1.setRows(5);
        jTextArea1.setText("eHOST has imported an unknown relationship.  Please define the regular expression that matches the allowed classes for this relationship.  \n");
        jTextArea1.setWrapStyleWord(true);
        jScrollPane1.setViewportView(jTextArea1);

        Head.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        getContentPane().add(Head, java.awt.BorderLayout.PAGE_START);

        End.setLayout(new java.awt.BorderLayout());

        jPanel3.setLayout(new java.awt.GridLayout(4, 1, 10, 10));

        jPanel9.setLayout(new java.awt.BorderLayout());

        BodyTitle.setText("Imported Name:");
        jPanel9.add(BodyTitle, java.awt.BorderLayout.LINE_START);

        nameLabel.setToolTipText("<html>\nRed: The relationship name is already in the schema.<br/>\nWhite: The relationship name is new to the schema.\n</html>");
        nameLabel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nameLabelActionPerformed(evt);
            }
        });
        nameLabel.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                nameLabelKeyReleased(evt);
            }
        });
        jPanel9.add(nameLabel, java.awt.BorderLayout.CENTER);

        jPanel3.add(jPanel9);

        jPanel6.setLayout(new java.awt.BorderLayout());

        userRegex.setToolTipText("<html>\nWhite: Regular expression is good and matches all Imported Relationships.<br/>\nYellow: Valid regular expression, but doesn't contain all imported relationships.<br/>\nRed: Regular expression does not fit within guidelines.\n</html>");
        userRegex.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                userRegexKeyReleased(evt);
            }
        });
        jPanel6.add(userRegex, java.awt.BorderLayout.CENTER);

        jLabel1.setText("   Actual Regex:");
        jPanel6.add(jLabel1, java.awt.BorderLayout.LINE_START);

        jButton2.setText("Help");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        jPanel6.add(jButton2, java.awt.BorderLayout.LINE_END);

        jPanel3.add(jPanel6);

        jPanel4.setLayout(new java.awt.GridLayout(1, 3));

        jPanel5.setLayout(new java.awt.BorderLayout());
        jPanel4.add(jPanel5);

        jPanel8.setLayout(new java.awt.BorderLayout());

        jButton1.setText("Delete All Relationships");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jPanel8.add(jButton1, java.awt.BorderLayout.CENTER);

        jPanel4.add(jPanel8);

        jButton3.setText("Delete Current Relationship");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });
        jPanel4.add(jButton3);

        jPanel3.add(jPanel4);

        jPanel7.setLayout(new java.awt.GridLayout(1, 0));

        skipAll.setText("Skip All");
        skipAll.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                skipAllActionPerformed(evt);
            }
        });
        jPanel7.add(skipAll);

        skip.setText("Skip");
        skip.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                skipActionPerformed(evt);
            }
        });
        jPanel7.add(skip);

        next.setText("Save & Continue");
        next.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextActionPerformed(evt);
            }
        });
        jPanel7.add(next);

        jPanel3.add(jPanel7);

        End.add(jPanel3, java.awt.BorderLayout.CENTER);

        getContentPane().add(End, java.awt.BorderLayout.PAGE_END);

        Body.setLayout(new java.awt.BorderLayout());

        jPanel1.setLayout(new java.awt.GridLayout(1, 1));

        jLabel2.setText("Imported Regular Expressions:");
        jPanel1.add(jLabel2);

        Body.add(jPanel1, java.awt.BorderLayout.PAGE_START);

        jPanel2.setLayout(new java.awt.BorderLayout());

        jScrollPane2.setViewportView(importedInfoList);

        jPanel2.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        Body.add(jPanel2, java.awt.BorderLayout.CENTER);

        getContentPane().add(Body, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    //<editor-fold defaultstate="collapsed" desc="Event Handling Methods">
    private void userRegexActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_userRegexActionPerformed
    {//GEN-HEADEREND:event_userRegexActionPerformed
        
    }//GEN-LAST:event_userRegexActionPerformed

    private void skipActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_skipActionPerformed
    {//GEN-HEADEREND:event_skipActionPerformed
        movePosition(true);
    }//GEN-LAST:event_skipActionPerformed

    private void skipAllActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_skipAllActionPerformed
    {//GEN-HEADEREND:event_skipAllActionPerformed
        caller.finished();
        this.dispose();
    }//GEN-LAST:event_skipAllActionPerformed

    private void userRegexKeyReleased(java.awt.event.KeyEvent evt)//GEN-FIRST:event_userRegexKeyReleased
    {//GEN-HEADEREND:event_userRegexKeyReleased
        setButtonsBasedOnValidity();
    }//GEN-LAST:event_userRegexKeyReleased

    private void nextActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_nextActionPerformed
    {//GEN-HEADEREND:event_nextActionPerformed
        makeNewComplexRel();
        movePosition(true);
}//GEN-LAST:event_nextActionPerformed

    private void nameLabelKeyReleased(java.awt.event.KeyEvent evt)//GEN-FIRST:event_nameLabelKeyReleased
    {//GEN-HEADEREND:event_nameLabelKeyReleased
        setButtonsBasedOnValidity();
    }//GEN-LAST:event_nameLabelKeyReleased

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton3ActionPerformed
    {//GEN-HEADEREND:event_jButton3ActionPerformed
        Depot depot = new Depot();
        //Delete all unknown relatinoships/attributes
        for(Annotation annotation: depot.getAllAnnotations())
        {
            //Annotation is unverified if it is still new
            if(!annotation.isVerified())
            {
                //Make sure we have some ComplexRelationships before trying to delete them
                if(annotation.relationships != null)
                {
                    //Delete unknown relationships
                    for(int i = 0; i< annotation.relationships.size(); i++)
                    {
                        AnnotationRelationship rel = annotation.relationships.get(i);

                        //If a selected relatinoship has the same name as the annotation then
                        //delete the relationship from the annotation
                        ComplexRelImportReturn newOnes = unknownRels.get(position);
                        {
                            if(newOnes.getName().equals(rel.getMentionSlotID()))
                            {
                                //TODO: Only delete relationships that match regex being delted.
                                annotation.relationships.remove(i);
                                i--;
                            }
                        }
                    }
                }
            }
        }
        movePosition(true);
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton1ActionPerformed
    {//GEN-HEADEREND:event_jButton1ActionPerformed
        Depot depot = new Depot();
        //Delete all unknown relatinoships/attributes
        for(Annotation annotation: depot.getAllAnnotations())
        {
            //Annotation is unverified if it is still new
            if(!annotation.isVerified())
            {
                //Make sure we have some ComplexRelationships before trying to delete them
                if(annotation.relationships != null)
                {
                    //Delete unknown relationships
                    for(int i = 0; i< annotation.relationships.size(); i++)
                    {
                        AnnotationRelationship rel = annotation.relationships.get(i);

                        //If a selected relatinoship has the same name as the annotation then
                        //delete the relationship from the annotation
                        for(ComplexRelImportReturn newOnes: unknownRels)
                        {
                            if(newOnes.getName().equals(rel.getMentionSlotID()))
                            {
                                //TODO: Only delete relationships that match regex being delted.
                                annotation.relationships.remove(i);
                                i--;
                            }
                        }
                    }
                }
            }
        }
        caller.finished();
        this.dispose();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosing
    {//GEN-HEADEREND:event_formWindowClosing
        
    }//GEN-LAST:event_formWindowClosing

    private void formWindowClosed(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosed
    {//GEN-HEADEREND:event_formWindowClosed
        
    }//GEN-LAST:event_formWindowClosed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        ComplexRelationshipInfo info = new ComplexRelationshipInfo(this);
        info.setVisible(true);
    }//GEN-LAST:event_jButton2ActionPerformed

    private void nameLabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameLabelActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_nameLabelActionPerformed
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Private Methods">
    /**
     * This method will update the State of the gui based on the values in the
     * text boxes for the Name and the Regular Expression for a relationship.
     * The background color of the text boxes will be red if the value is not
     * valid.
     */
    private void setButtonsBasedOnValidity()
    {
        //Verify that the regular expression and name that the user entered is valid
        boolean goodRegex = VerifyRegexWithClasses.CheckValidRegex(userRegex.getText()) && !userRegex.getText().equals("");
        boolean goodName = !nameLabel.getText().equals("");

        //Verify that the relationship name and regular expression are unique to the schema.
        boolean nameExists = env.Parameters.RelationshipSchemas.checkNameExists(nameLabel.getText());
        boolean regexExists = env.Parameters.RelationshipSchemas.checkRegexExists(userRegex.getText());

        boolean regexMatchesAllClasses = this.checkRegexHoldsAll(userRegex.getText());

        //Concatenate boolean results to be more useful
        boolean regexReady = goodRegex && !regexExists;
        boolean nameReady = goodName && !nameExists;
        boolean everythingReady = nameReady & regexReady;

        //If everything is good enable the 'next' button and set background color
        //of regex bar to green.
        if(everythingReady)
        {
            if(!regexMatchesAllClasses)
            {
                userRegex.setBackground(new Color(255,255,0));
            }
            else
            {
                userRegex.setBackground(new Color(255,255,255));
            }
            nameLabel.setBackground( new Color(255,255,255));
            next.setEnabled(true);
        }

        //Regex is bad or already exists in schema...
        else
        {
            if(!regexReady)
            {
                userRegex.setBackground(new Color(255,150,150));
            }
            else if (!regexMatchesAllClasses)
            {
                userRegex.setBackground(new Color(255,255,0));
            }
            else
                userRegex.setBackground(new Color(255,255,255));
            if(!nameReady)
                nameLabel.setBackground(new Color(255,150,150));
            else
                nameLabel.setBackground(new Color(255,255,255));
             
            next.setEnabled(false);
        }
    }
    private boolean checkRegexHoldsAll(String regex)
    {
        return VerifyRegexWithClasses.checkRegexFitsAll(regex,this.unknownRels.get(position).getClassesConcatenated());
    }
    /**
     * Make a new Complex Relationship with the current GUI information.
     */
    private void makeNewComplexRel()
    {
         RelationshipDef rel = new RelationshipDef(nameLabel.getText(), userRegex.getText());
         env.Parameters.RelationshipSchemas.add(rel);
    }
    /**
     * Increment or decrement the relationship we're currently looking at.
     * @param forward - true if incrementing, false if decrementing.
     */
    private void movePosition(boolean forward)
    {
        //Assume we're not going to change anything...
        boolean changed = false;

        //incrementing/moving forwards
        if(forward)
        {
            if(position == unknownRels.size() -1)
            {
                caller.finished();
                 this.dispose();
            }

            else if(position == unknownRels.size() -2)
            {
                position++;
                changed =true;
                next.setText("Done");
            }
            else
            {
                changed = true;
                position++;
            }
        }
        //Decrementing/moving backwards
        else
        {
            if(position >= 1)
            {
                position --;
                changed = true;
            }
            else
            {
                //Do nothing... can't move backwards anymore.
            }
        }
        if(changed)
        {
            userRegex.setText("");
        }
        updateInfo();
        setButtonsBasedOnValidity();
    }
    /**
     * Update the info in the GUI based on the position in the list of imported
     * relationships.
     */
    private void updateInfo()
    {

        nameLabel.setText(unknownRels.get(position).getName());
        Vector<String> toSet = new Vector<String>();

        for(String s: unknownRels.get(position).getRegex())
        {
            toSet.add(s);
        }
        importedInfoList.setListData(toSet);
        setButtonsBasedOnValidity();
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="GUI Member Variables">
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel Body;
    private javax.swing.JLabel BodyTitle;
    private javax.swing.JPanel End;
    private javax.swing.JPanel Head;
    private javax.swing.JList importedInfoList;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField nameLabel;
    private javax.swing.JButton next;
    private javax.swing.JButton skip;
    private javax.swing.JButton skipAll;
    private javax.swing.JTextField userRegex;
    // End of variables declaration//GEN-END:variables
    //</editor-fold>
}
